package com.ailanyin.modules.file.utils;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import com.ailanyin.common.base.exception.Assert;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;

/**
 * 文件工具类
 *
 * @author ailanyin
 * @version 1.0
 * @since 2021/10/25 0025 上午 9:15
 */
public class FileUtil {

    private static final String FILE_URL = "URL";

    private static final String[] DEFAULT_ALLOWED_EXTENSION = {
            // 图片
            "bmp" , "gif" , "jpg" , "jpeg" , "png" ,
            // word excel powerpoint
            "doc" , "docx" , "xls" , "xlsx" , "ppt" , "pptx" , "html" , "htm" , "txt" ,
            // 压缩文件
            "rar" , "zip" , "gz" , "bz2" ,
            // 音频
            "mp3" , "wav" , "wma" , "mp2" , "flac" , "midi" , "ra" , "ape" , "aac" , "cda" , "mov" ,
            // 视频
            "mp4" , "avi" , "rmvb" , "blob" ,
            // pdf
            "pdf"};


    /**
     * @param file 上传的文件
     * @return 文件全路径名称
     */
    public static String upload(MultipartFile file, HttpServletRequest request, String path, String dir) {

        // 获取文件后缀名
        String extension = getExtension(file);
        // 判断是否允许上传
        isAllowedExtension(extension);
        // 重命名文件
        String fileName = extractFilename(extension);

        path = path + dir;
        // 新建文件
        File newFile = getAbsoluteFile(fileName, path);
        try {
            file.transferTo(newFile);
            return getPathFileName(fileName, path, dir);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 判断文件类型是否是允许上传的类型
     *
     * @param extension 文件类型
     */
    private static void isAllowedExtension(String extension) {
        boolean flag = true;
        for (String str : DEFAULT_ALLOWED_EXTENSION) {
            if (str.equalsIgnoreCase(extension)) {
                flag = false;

            }
        }

        if (flag) {
            Assert.fail("不允许上传改文件类型");
        }
    }

    /**
     * 获取文件名的后缀
     *
     * @param file 表单文件
     * @return 后缀名
     */
    public static String getExtension(MultipartFile file) {
        String fileName = file.getOriginalFilename();
        if (fileName == null || "".equals(fileName.trim())) {
            throw new RuntimeException("上传文件-获取文件后缀名失败");
        }
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    }

    /**
     * 编码文件名(UUID去除-)
     */
    private static String extractFilename(String extension) {
        return UUID.fastUUID().toString(true) + "." + extension;
    }

    /**
     * 创建文件
     *
     * @param fileName 文件名
     * @return file
     */
    private static File getAbsoluteFile(String fileName, String path) {
        File desc = new File(path + File.separator + fileName);

        if (!desc.exists()) {
            if (!desc.getParentFile().exists()) {
                boolean result = desc.getParentFile().mkdirs();
                if (!result) {
                    Assert.fail("上传文件-创建父目录失败");
                }
            }
        }
        return desc;
    }

    private static String getPathFileName(String fileName, String path, String dir) {
        int dirLastIndex = path.length() + 1;
        String currentDir = StringUtils.substring(path, dirLastIndex);
        return currentDir + "/file/" + dir + fileName;
    }

    private static String getUrl(HttpServletRequest request) {
        // 解决nginx反向代理后代理前缀丢失的问题
        if (StrUtil.isNotEmpty(request.getHeader(FILE_URL))) {
            return request.getHeader(FILE_URL);
        }
        StringBuffer url = request.getRequestURL();
        String contextPath = request.getServletContext().getContextPath();
        return url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString();
    }

}
